﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Xml;
using System.Xml.Linq;
using TV4Home.Server.TVEInteractionLibrary;
using TV4Home.Server.TVEInteractionLibrary.Interfaces;

namespace TV4Home.WebInterface.UI
{
    public class SearchTVPrograms : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            #region Process QueryString inputs
            string searchTerm = context.Request.QueryString["term"];
            string searchMode = context.Request.QueryString["searchmode"];

            if (String.IsNullOrEmpty(searchTerm))
                return;

            if (String.IsNullOrEmpty(searchMode))
                searchMode = "0";
            #endregion

            #region Search database for query
            List<WebProgramBasic> searchResults = null;

            try
            {
                searchResults = WebService.TV4HomeWebService.ServiceInstance.SearchProgramsBasic(searchTerm);
            }
            catch (Exception) { }

            if (searchResults == null)
                return;
            #endregion

            #region Output results
            XmlTextWriter xmlWr = new XmlTextWriter(context.Response.OutputStream, Encoding.UTF8);

            switch (searchMode)
            {
                case "0":  // used for search results in RSS format (-> Windows 7 Federated Search or via browser searchbox)

                    context.Response.ContentType = "application/rss+xml";

                    SyndicationFeed searchResultsFeed = new SyndicationFeed
                                                            {
                                                                Title = new TextSyndicationContent(Properties.Resources.SearchTVPrograms_Win7FedSearch_ResultTitle),
                                                                Description = new TextSyndicationContent(Properties.Resources.SearchTVPrograms_Win7FedSearch_ResultDescription),
                                                                Copyright = new TextSyndicationContent(Properties.Resources.SearchTVPrograms_Win7FedSearch_ResultCopyright),
                                                                Items = from item in searchResults
                                                                        select new SyndicationItem(GetTitleForItem(item), GetDescriptionForItem(item), GetLinkToProgramInfoDialog(item, context.Request))
                                                            };

                    searchResultsFeed.AttributeExtensions.Add(new XmlQualifiedName("media", "http://www.w3.org/2000/xmlns/"), "http://search.yahoo.com/mrss/");
                    searchResultsFeed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri(context.Request.Url.GetLeftPart(UriPartial.Authority) + VirtualPathUtility.ToAbsolute("~/SearchTVPrograms.ashx"))));

                    searchResultsFeed.SaveAsRss20(xmlWr);

                    xmlWr.Flush();
                    xmlWr.Close();

                    break;
                case "1": // used for search suggestions in JSON format, FF
                case "3": // used for search suggestions in JSON format, jQuery Autocomplete

                    context.Response.ContentType = "text/plain";

                    JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();

                    // get the titles of the shows and remove duplicate entries (e.g. from shows with the same name aired on different dates)
                    var showTitles = (from x in searchResults select x.Title).Distinct().Take(10);

                    string results = "";

                    if (searchMode == "1") // FF
                        results = String.Format("[\"{0}\",{1}]", searchTerm, jsonSerializer.Serialize(showTitles));
                    else if (searchMode == "3")  // jQuery Autocomplete
                        results = jsonSerializer.Serialize(showTitles);

                    context.Response.Write(results);

                    break;
                case "2":  // used for search suggestions in XML format (-> IE)

                    context.Response.ContentType = "text/xml";

                    new XDocument(new XElement("SearchSuggestion",
                                               new XAttribute("version", "2.0"),
                                               new XAttribute("xmlns", "http://opensearch.org/searchsuggest2"),
                                               new XElement("Query", searchTerm),
                                               new XElement("Section",
                                                            new XAttribute("title", String.Format(Properties.Resources.SearchTVPrograms_SearchSuggestionsXML_ResultTitle, searchResults.Count)),
                                                            from item in searchResults.Distinct().Take(10)
                                                            select new XElement("Item",
                                                                                new XElement("Text", item.Title),
                                                                                new XElement("Description", item.Description)))))
                        .Save(xmlWr);

                    xmlWr.Flush();
                    xmlWr.Close();

                    break;
                default:
                    throw new NotSupportedException("Search mode not supported!");
            }

            context.Response.End();
            #endregion
        }

        private Uri GetLinkToProgramInfoDialog(WebProgramBasic item, HttpRequest request)
        {
            return new Uri(request.Url.GetLeftPart(UriPartial.Authority) + VirtualPathUtility.ToAbsolute("~/ProgramInfoDialog.aspx") + "?id=" + item.IdProgram);
        }

        private string GetDescriptionForItem(WebProgramBasic item)
        {
            return item.Description.Replace("\n", "<br/>");
        }

        private string GetTitleForItem(WebProgramBasic item)
        {
            return String.Format(CultureInfo.CurrentCulture,
                                 "{0} ({1}, {2}, {3}-{4})",
                                 item.Title,
                                 WebService.TV4HomeWebService.ServiceInstance.GetChannelBasicById(item.IdChannel).DisplayName,
                                 item.StartTime.ToLongDateString(),
                                 item.StartTime.ToShortTimeString(),
                                 item.EndTime.ToShortTimeString());
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
